<template>
    <div class="page">
        <!-- 顶部栏 -->
        <div class="page-header">
            <div class="title-wrap">
                <span class="status-dot"></span>
                <h2 class="title">预约挂号</h2>
            </div>
            <div class="actions">
                <input type="file" ref="fileInput" accept=".xlsx,.xls" style="display: none"
                    @change="handleFileSelect" />
                <button class="btn btn-secondary" :disabled="importing" @click="triggerFileSelect">
                    <span v-if="importing" class="loading-spinner"></span>
                    {{ importing ? '导入中...' : '导入' }}
                </button>
                <button class="btn btn-primary" :disabled="exporting" @click="handleExport">
                    <span v-if="exporting" class="loading-spinner"></span>
                    {{ exporting ? '导出中...' : '导出' }}
                </button>
            </div>
        </div>

        <!-- 筛选区 -->
        <div class="filter-card">
            <div class="filter-row">
                <label class="radio">
                    <input type="radio" name="status" checked />
                    <span>全部</span>
                </label>
                <label class="radio">
                    <input type="radio" name="status" />
                    <span>待就诊</span>
                </label>
                <label class="radio">
                    <input type="radio" name="status" />
                    <span>已就诊</span>
                </label>
                <label class="radio">
                    <input type="radio" name="status" />
                    <span>已取消</span>
                </label>

                <div class="spacer"></div>

                <div class="field">

                    <el-form-item label="请选择时间" style="margin-top: 15px;">~&nbsp;
                        <el-date-picker v-model="page.AppointmentTime" type="date" placeholder="请选择时间" clearable />
                    </el-form-item>
                    <button class="icon-btn" title="日期">
                        <span>📅</span>
                    </button>
                </div>

                <div class="field">
                    <el-form-item>
            <el-cascader
              v-model="page.DepartmentId"
              :options="options"
              :props="props1"
              placeholder="请选择科室"
              class="search-select"
            />
          </el-form-item>
                </div>

                <div class="field grow" style="margin-top: 15px;">
                    <el-form-item label="">
                        <el-input v-model="page.Name" placeholder="请输入医生/病人姓名" clearable />
                    </el-form-item>
                </div>
                <button class="btn btn-primary" @clisk="appointList()">搜索</button>
            </div>
        </div>

        <!-- 表格 -->
        <div class="table-card">
            <table class="table">
                <thead>
                    <tr>
                        <th style="width: 40px">
                            <input type="checkbox" v-model="selectAll" @change="toggleSelectAll" />
                        </th>
                        <th>患者姓名</th>
                        <th>就诊卡号</th>
                        <th>身份证号</th>
                        <th>手机号</th>

                        <th>挂号科室 ?</th>

                        <th>挂号类型</th>
                        <th>挂号费</th>
                        <th>挂号状态</th>
                        <th>就诊时间</th>
                        <th>候诊时间</th>
                        <th>预约时间</th>

                        <th style="width: 80px">操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="row in rows" :key="row.patientId">
                        <td><input type="checkbox" v-model="selectedRows" :value="row.patientId"
                                @change="updateSelectAll" /></td>
                        <td>{{ row.name }}</td>
                        <td>{{ row.idCardType }}</td>

                        <td>{{ row.medicalCard }}</td>
                        <td>{{ row.phone }}</td>

                        <td>{{ row.departmentName }}</td>
                        <td>{{ row.registerName }}</td>
                        <td>{{ row.cost.toFixed(2) }}</td>

                        <td>
                            <span :class="['status', row.medicalState ? 'ok' : 'wait']">{{ row.medicalState ? '已就诊' :
                                '待就诊' }}</span>
                        </td>

                        <td>{{ moment(row.outpatientTime).format('YYYY-MM-DD') }}</td>
                        <td>{{ moment(row.waitingTime).format('HH:mm YYYY-MM-DD') }}</td>
                        <td>{{ moment(row.appointmentTime).format('YYYY-MM-DD HH:mm:ss') }}</td>

                        <td>
                            <button class="icon-btn" title="详情" @click="Details(row)">🗂️</button>
                        </td>
                    </tr>
                </tbody>
                <el-pagination v-model:current-page="page.pageIndex" v-model:page-size="page.pageSize"
                    :page-sizes="[5, 10, 15]" :background="true" layout="total, sizes, prev, pager, next, jumper,slot"
                    prev-text="上一页" next-text="下一页" :total="page.totalCount" />
            </table>
        </div>
    </div>

</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import moment from 'moment'
import axios from 'axios'
import { dataRead } from '@/Utils/Http'
import * as XLSX from 'xlsx'


const router = useRouter()

// 多选相关状态
const selectAll = ref(false)
const selectedRows = ref<number[]>([])
const importing = ref(false)
const exporting = ref(false)
const fileInput = ref<HTMLInputElement>()

//参数与字段定义
type Row = {
    attending: string
    doctorAddress: string
    department: string
    attendingName: string
    doctorName: string
    registTypeId: number
    outpatientTime: string
    waitingTime: string
    cost: number
    appointmentTime: string 
    medicalState: boolean
    reason: string
    cancelTime: string
    desc: string
    registerName: string
    patientId: number
    relationship: string
    name: string
    idCardType: string
    idCardNum: string
    medicalCard: string
    phone: string
    departmentName: string
}

//预约挂号列表数据
const rows = ref<Row[]>(Array.from({ length: 12 }).map((_, i) => ({
    attending: '',
    doctorAddress: '',
    department: '',
    attendingName: '',
    doctorName: '',
    registTypeId: 1 + (i % 2),
    outpatientTime: '',
    waitingTime: '',
    cost: 120,
    appointmentTime: '',
    medicalState: i % 2 === 0,
    reason: i % 3 === 0 ? '' : '—',
    cancelTime: i % 3 === 0 ? '' : '',
    desc: '',
    registerName: '',
    patientId: i + 1,
    relationship: i % 2 === 0 ? '本人' : '家属',
    name: '',
    idCardType: '',
    idCardNum: '',
    medicalCard: '',
    phone: '',
    departmentName: '',
})))

//分页参数
const page = reactive({
    pageIndex: 1,
    pageSize: 5,
    "totalCount": 0,
    "pageCount": 0,
    DepartmentId:'',
    AppointmentTime: '',
    Name: '',
})

//预约挂号列表数据获取
const appointList = () => {
    dataRead.get('/Appoint/ShowAppintList', { params: page })
        .then(res => {
            const data = (res && (res.data.data ?? res)) as any
            const items = (data?.items ?? data?.data ?? data?.list ?? []) as Row[]
            rows.value = Array.isArray(items) ? items : []

            if (typeof data?.totalCount === 'number') page.totalCount = data.totalCount
            if (typeof data?.pageCount === 'number') page.pageCount = data.pageCount
            console.log('预约挂号列表数据：', data)
            page.totalCount = res.data.data.totalCount
            page.pageCount = res.data.data.pageCount
        })
        .catch(() => {
            ElMessage.error('数据加载失败')
        })
}

//分页监听
watch(page, () => {
    appointList()
})

//初始加载 钩子
onMounted(() => {
    appointList()
    fetchDepartments();
})


// 科室级联数据
const options = ref([])
const fetchDepartments = () => {
  dataRead.get("/Manage/Handle")
    .then(res => {
      options.value = res.data.data || []
    })
}
const props1 = {
  checkStrictly: true,
  emitPath: false,
}

// 点击详情，跳转到 Details 页面并携带参数（含头像样式）
const Details = (row: Row) => {
    const avatarStyle = {
        width: '64px',
        height: '64px',
        borderRadius: '50%'
    }
    router.push({
        name: 'Details',
        query: {
            payload: encodeURIComponent(JSON.stringify(row)),
            avatarStyle: encodeURIComponent(JSON.stringify(avatarStyle))
        }
    })
}

// 全选/取消全选
const toggleSelectAll = () => {
    if (selectAll.value) {
        selectedRows.value = rows.value.map(row => row.patientId)
    } else {
        selectedRows.value = []
    }
}

// 更新全选状态
const updateSelectAll = () => {
    selectAll.value = selectedRows.value.length === rows.value.length && rows.value.length > 0
}

// 触发文件选择
const triggerFileSelect = () => {
    if (selectedRows.value.length === 0) {
        ElMessage.warning('请先选择要导入数据的位置（选择行）')
        return
    }
    fileInput.value?.click()
}

// 处理文件选择
const handleFileSelect = async (event: Event) => {
    const target = event.target as HTMLInputElement
    const file = target.files?.[0]

    if (!file) return

    if (!file.name.match(/\.(xlsx|xls)$/)) {
        ElMessage.error('请选择Excel文件（.xlsx或.xls格式）')
        return
    }

    importing.value = true
    try {
        const data = await readExcelFile(file)
        await processImportData(data)
        ElMessage.success(`成功导入 ${data.length} 条数据到选中位置`)
        appointList() // 重新加载数据
    } catch (error) {
        console.error('导入失败:', error)
        ElMessage.error('导入失败，请检查文件格式')
    } finally {
        importing.value = false
        // 清空文件选择
        if (target) target.value = ''
    }
}

// 读取Excel文件
const readExcelFile = (file: File): Promise<any[]> => {
    return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = (e) => {
            try {
                const data = e.target?.result
                const workbook = XLSX.read(data, { type: 'binary' })
                const sheetName = workbook.SheetNames[0]
                const worksheet = workbook.Sheets[sheetName]
                const jsonData = XLSX.utils.sheet_to_json(worksheet)
                resolve(jsonData)
            } catch (error) {
                reject(error)
            }
        }
        reader.onerror = () => reject(new Error('文件读取失败'))
        reader.readAsBinaryString(file)
    })
}

// 处理导入数据
const processImportData = async (data: any[]) => {
    // 模拟处理导入数据的过程
    await new Promise(resolve => setTimeout(resolve, 1000))

    // 这里可以将数据发送到后端API
    // 或者直接更新本地数据
    console.log('导入的数据:', data)
    console.log('选中的位置:', selectedRows.value)

    // 模拟API调用
    // await dataRead.post('/Appoint/ImportData', {
    //     data: data,
    //     targetRows: selectedRows.value
    // })
}

// 导出功能
const handleExport = async () => {
    if (selectedRows.value.length === 0) {
        ElMessage.warning('请先选择要导出的数据')
        return
    }

    exporting.value = true
    try {
        // 获取选中的数据
        const selectedData = rows.value.filter(row => selectedRows.value.includes(row.patientId))

        // 准备导出数据
        const exportData = selectedData.map(row => ({
            '患者姓名': row.name,
            '就诊卡号': row.medicalCard,
            '身份证号': row.idCardNum,
            '手机号': row.phone,
            '挂号科室': row.departmentName,
            '挂号类型': row.registerName,
            '挂号费': row.cost,
            '挂号状态': row.medicalState ? '已就诊' : '待就诊',
            '就诊时间': row.outpatientTime ? moment(row.outpatientTime).format('YYYY-MM-DD') : '',
            '候诊时间': row.waitingTime ? moment(row.waitingTime).format('HH:mm YYYY-MM-DD') : '',
            '预约时间': row.appointmentTime ? moment(row.appointmentTime).format('YYYY-MM-DD HH:mm:ss') : '',
            '就诊医院': row.attending,
            '医院地址': row.doctorAddress,
            '就诊科室': row.department,
            '就诊医生': row.attendingName,
            '医生职称': row.doctorName,
            '取消原因': row.reason || '',
            '取消时间': row.cancelTime ? moment(row.cancelTime).format('YYYY-MM-DD HH:mm:ss') : '',
            '备注': row.desc || ''
        }))

        // 创建工作簿
        const wb = XLSX.utils.book_new()
        const ws = XLSX.utils.json_to_sheet(exportData)

        // 设置列宽
        const colWidths = [
            { wch: 10 }, // 患者姓名
            { wch: 15 }, // 就诊卡号
            { wch: 20 }, // 身份证号
            { wch: 12 }, // 手机号
            { wch: 15 }, // 挂号科室
            { wch: 10 }, // 挂号类型
            { wch: 8 },  // 挂号费
            { wch: 10 }, // 挂号状态
            { wch: 12 }, // 就诊时间
            { wch: 15 }, // 候诊时间
            { wch: 20 }, // 预约时间
            { wch: 20 }, // 就诊医院
            { wch: 25 }, // 医院地址
            { wch: 15 }, // 就诊科室
            { wch: 10 }, // 就诊医生
            { wch: 10 }, // 医生职称
            { wch: 15 }, // 取消原因
            { wch: 20 }, // 取消时间
            { wch: 15 }  // 备注
        ]
        ws['!cols'] = colWidths

        // 添加工作表到工作簿
        XLSX.utils.book_append_sheet(wb, ws, '预约挂号数据')

        // 生成文件名
        const fileName = `预约挂号数据_${moment().format('YYYY-MM-DD_HH-mm-ss')}.xlsx`

        // 导出文件
        XLSX.writeFile(wb, fileName)

        ElMessage.success(`成功导出 ${selectedRows.value.length} 条数据到 ${fileName}`)
    } catch (error) {
        console.error('导出失败:', error)
        ElMessage.error('导出失败')
    } finally {
        exporting.value = false
    }
}


</script>

<style scoped>
.page {
    padding: 16px 20px 28px;
}

.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: #f7f9fc;
    border: 1px solid #eef0f3;
    border-radius: 8px;
    padding: 14px 16px;
    margin-bottom: 16px;
}

.title-wrap {
    display: flex;
    align-items: center;
    gap: 8px;
}

.status-dot {
    width: 10px;
    height: 10px;
    background: #409eff;
    border-radius: 50%;
    display: inline-block;
}

.title {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #1f2d3d;
}

.actions {
    display: flex;
    gap: 8px;
}

.btn {
    padding: 6px 12px;
    border-radius: 4px;
    border: 1px solid transparent;
    font-size: 14px;
    cursor: pointer;
}

.btn-primary {
    background: #409eff;
    color: #fff;
    border-color: #409eff;
}

.btn-secondary {
    background: #fff;
    color: #606266;
    border-color: #dcdfe6;
}

.btn:active {
    transform: translateY(1px);
}

.filter-card {
    background: #fff;
    border: 1px solid #eef0f3;
    border-radius: 8px;
    padding: 12px 12px;
    margin-bottom: 12px;
}

.filter-row {
    display: flex;
    align-items: center;
    gap: 12px;
}

.radio {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: #606266;
}

.spacer {
    flex: 1;
}

.field {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.field.grow {
    flex: 0 0 280px;
}

.input,
.select {
    height: 32px;
    padding: 0 10px;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    background: #fff;
    outline: none;
}

.input {
    width: 160px;
}

.select {
    width: 160px;
}

.sep {
    color: #a8abb2;
}

.icon-btn {
    width: 32px;
    height: 32px;
    border: 1px solid #dcdfe6;
    background: #fff;
    border-radius: 4px;
    cursor: pointer;
}

.table-card {
    background: #fff;
    border: 1px solid #eef0f3;
    border-radius: 8px;
    overflow: hidden;
}

.table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

.table thead th {
    background: #f5f7fa;
    color: #606266;
    font-weight: 600;
    text-align: left;
    padding: 12px 10px;
    border-bottom: 1px solid #ebeef5;
}

.table tbody td {
    padding: 12px 10px;
    color: #303133;
    border-bottom: 1px solid #f2f3f5;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.status {
    font-weight: 600;
}

.status.ok {
    color: #67c23a;
}

.status.wait {
    color: #e6a23c;
}

.status.cancel {
    color: #909399;
}

/* 加载动画 */
.loading-spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid #f3f3f3;
    border-top: 2px solid #409eff;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin-right: 6px;
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

/* 按钮禁用状态 */
.btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}
</style>
